Android 恶意应用检测系统分析

安卓恶意软件检测:系统调用日志+机器学习算法:https://cloud.tencent.com/developer/article/1016644

深度安卓恶意软件检测系统:用卷积神经网络保护你的手机:http://www.bijishequ.com/detail/430137?p=

基于随机森林分类方法的Android平台恶意应用检测方法:https://patents.google.com/patent/CN105550583A/zh

基于机器学习算法的 Android 恶意程序检测系统:https://patents.google.com/patent/CN104123500B/en

基于BHNB的细粒度的Android恶意应用检测模型:http://www.shcas.net/jsjyup/pdf/2017/10/%E5%9F%BA%E4%BA%8EBHNB%E7%9A%84%E7%BB%86%E7%B2%92%E5%BA%A6%E7%9A%84Android%E6%81%B6%E6%84%8F%E5%BA%94%E7%94%A8%E6%A3%80%E6%B5%8B%E6%A8%A1%E5%9E%8B.pdf

基于 API 调用的抗混淆 Android 应用相似性检测方法:http://sei.pku.edu.cn/~yaoguo/papers/Wang-ScienceChina-14.pdf

基于代码克隆检测技术的 Android 应用重打包检测http://sei.pku.edu.cn/~yaoguo/papers/Wang-ScienceChina-14.pdf

如何分析

对任何软件的分析基本都可以概括为两方面,静态分析以及动态分析。

静态分析

在不运行程序的情况下,反编译、模式识别、解密等,提取分析程序的静态特征

获取目标信息 描述
Apk本身 提取安装文件的MD5值
文件MD5值 程序反编后的代的代码文件、配置、图片资源等MD5
包名 主进程标识
启动Activity名称 程序主界面标识
权限 配置中所有申请的权限信息
  • 缺点:因为未知的恶意应用因为使用混淆、加密等技术会使签名不同,所以静态分析方法不能识别未知的恶意软件。

可能使用的方法

  • Apk反编译和过滤,得到签名以及应用核心代码
  • 特征提取,计算每个变量的特征计数向量
  • 相似度分析,比较代码块与特征计数库中的相似度
  • 使用系统调用日志进行恶意软件检测

动态分析

动态分析方法可以检测应用的行为,比如网络访问、运行时发送短信和打电话等。动态分析是在沙箱环境下运行的,这样可以防止恶意软件感染真实的运行环境。

可能使用的方法

  1. 内核指令
  2. 系统调用
  3. Dalvik指令,Dalvik字节码通过Dalvik虚拟机翻译相应可执行的本地指令并执行,采用解释执行和实时编译两种方式来完成这一过程。 Dalvik的解释器模块名为mterp,采用地址偏移的方式将Dalvik操作码(opcode,指令编号)映射到机器码,每条操作都有64B的内存用于存储相对应模拟解释的本地代码,对于模拟解释不足64B的操作码,会进行填充,使其存储满64B,mterp计算偏移地址公式:NativeAddress = BaseAddress + opcode * 64,其中NativeAddress为操作码对应的本地代码,BaseAddress为存储操作码对应的对应本地代码的内存起始地址,Dalvik虚拟机可以通过此公式计算得到每个操作码对应的本地代码。

可能使用的算法

朴素贝叶斯算法、随机森林算法和随机下降梯度算法(Stochastic Descent Gradient Algorithm)。机器学习的结果会输出到Weka软件中进行分析。

Apk文件分析

Apk文件实质是一个压缩包,解压缩之后的文件夹主要包含Dalvik字节码,UI布局,资源文件,配置文件,签名信息等,

特征向量

  1. 权限特征

    Android 系统具有非常严格的权限管理机制,当用户使用系 统中的某个功能或访问某些敏感数据时都要申请某个使用权限。一般应用程序在不使用短信功能时是不会申请短信发送、 短信读写的权限。但恶意软件则不同,由于某些动机的存在, 例如吸费类恶意应用会申请 SEND_SMS 权限发送短信。由于某些正常的程序也会申请短信功能使用权限,因此仅仅根据应用 程序申请的权限判断一个应用程序是否存在恶意行为是不够的。但根据分析大量的恶意程序样本发现,存在恶意行为的应 用往往会使用大量敏感权限,其中使用频率较高的包括: INTERNET 、 READ_PHONE_STATE 、 SEND_SMS 、 WRITE_EXTERNAL_STORAGE 、 READ_SMS 、 ACCESS_NETWORK_STATE 、 READ_CONTACTS 、 CALL_PHONE、RECEIVE_SMS 等等。所以权限的使用从一个方面反映了恶意程序的某些行为特征。

  2. API 调用序列特征

    API 是操作系统为应用程序提供的服务性接口,应用程序在完成文件读写、网络访问以及其他重要资源的访问时都会调用API。恶意程序在实现某个特征功能时同样会调用功能相似的API 函数,因此通过提取API函数调用序列特征来识别恶意程序行为已成为通用一种做法,应用程序的 API 调用大致可以反映程序的行为。使用 API 调用作为特征,并利用数据挖掘的方法对数据进行分析

提取特征向量

  1. 提取权限特征 使用静态分析的方法,对应用程序自身 APK 文件进行解析 分析,提取应用程序在配置文件中申请的敏感权限信息。 Androguard是基于python的Android恶意应用程序检测工具, 可以提取大量敏感信息,其中 androapkinfo.py 模块分析并列出 应用程序的文件类型、权限、4 大组件、是否 NDK 反射等信息。 本文利用 androapkinfo.py 提取 APK 申请的敏感权限,将每个应 用的结果汇总为权限特征列表,提交数据统一建模模块。
  2. 提取 smali API 调用特征 Android 基于 Linux 内核,在架构上分为 5 个部分,包括 Linux Kernel、Android Runtime、Libraries、Application Framework 和 Application。Android 应用程序以 APK(Android Package)文件 结构发布,APK 文件是一个压缩包,其结构如图 3 所示, META-INF 用于存放签名信息,用来保证 APK 包的完整性;res 存储资源文件,包括图片 、字符串等;AndroidManifest.xml 是 应用程序的配置文件,其 中声明了应用程序的包名、SDK 版 本、权限、组件等信息;classes.dex 则是 dvm 字节码文件,可 运行于 Android 虚拟机 Dalvik 上。

相似度分析

为了分析相似度,需要计算两个应用之间相似代码块所占的比重,判断两个代码块是否相似的途径是比对代码块的特征计数矩阵。 对于两个应用程序 A 和 B, 在计算它们相似程度的时候, 考虑两个 值 PAinB 和 PBinA, 分别代表应用 A 代码块在应用 B 中被克隆的比例, 以及应用 B 中代码块在应用 A 中被克隆的比例. 取其中较大者作为判断这个应用对之间是否是重打包关系. 这样的做法主要是考 虑到有些重打包应用可能添加大量的无用代码来干扰相似度的计算, 或者一个大的应用重打包进去很多小应用的功能. 在这种重打包情况下, 由于原应用的核心代码没有发生改变, 这两个值中至少有一个应该比较大. 设定一个阈值 Pthres, 当 PAinB > Pthres 或者 PBinA > Pthres 时, 则判断出应用 A 和应用 B 是重打包关系.将 Pthres 设置为 60% 是比较合理的值.

  • 代码块的数量影响比较时间和空间效率,行数很少的代码块包含的信息很少,计算这些特征矩阵意义不大,代码行数不足5行可能会被系统过滤掉。
  • 代码块的两两比较是很耗时的过程, 严重影响比较的效率. 很多代码块的比较是无用的, 因为很多代码块差异很大, 明显是不相似的. 因此, 对每个代码块 提取它的元信息, 包括代码块的行数, 变量的个数, 变量的最大使用次数, 关键字总共出现的次数等. 代码块的元信息代表代码块的总体属性, 如果两个代码块的元信息差别很大, 可以认为这两个代码块是不相似的, 因此也不需要对代码块的特征计数矩阵进行比较. 元信息属性的差异程度体现在两方面: 一方面是两个属性的数值差别比较大, 比如代码行数 20 行与代码行数 35 行相比; 另一方面是两个属 性的比例差别比较大, 比如变量个数为 5 与变量个数为 10. 因此, 通过计算元信息中属性的数值差别与比例差别, 来判断是否需要进行更进一步的代码块比较。
  • 假定GP会维护一个现有应用的特征库. 每当应用的开发者在市场中准备发布一个新应用的时候, 系统会对该应用进行检查. 首先提取应用的特征, 然后在应用特征库中进行比对. 如果没有发现相似包的可能, 那么应用就可以发布, 新应用的特征被加入到应用特征库中. 如果发现提交的应用跟特征库中的应用相似并且签名信息不同, 那么提交的应用就要被暂时禁止发布并且进行进一步审核.

业界使用技术

  1. DroidMOSS 在 Dalvik 字节码层进行应用重打包检测. DroidMOSS 提取 Dalvik 字节码中的操作码序列, 使用模糊散列的方法对应用程序产生一个指纹签名并作为特征, 通过比较应用程序指纹之间的编辑距离得到应用程序的相似度. 类似的, Juxtapp[5] 使用了特征散列 的方法对应用程序产生指纹签名并且以它们之间的 Jaccard 距离作为重打包的判断依据. DroidMOSS 和 Juxtapp 都是从 Dalvik 字节码中提取静态的特征信息, 并且使用不同的散列技术来将这些静态信 息表示成向量从而进行比较. 这种比较方法的优点是简单快速, 能够很容易的扩展到大规模应用的比 较. 但是重打包应用很容易就能逃避这种检查技术, 比如最简单的交换代码顺序或者增添删除操作码 就会导致应用程序的指纹发生改变从而导致检测方法失效.

  2. DNADroid通过比较应用的程序依赖图 (PDG) 来检测重打包应用. 基于程序依赖图的检测技 术是代码克隆检测中经常使用的方法. 它使用了程序的语义信息, 因此检测的准确率应该会比较高. 但是基于程序依赖图的检测方法执行效率是个问题. 在 DNADroid 中, 作者使用 Hadoop Mapreduce 并行计算框架在四台机器上执行应用的重打包检测, 但是平均每分钟只能比较 0.71 个应用对. 因此, 这种方法的扩展性不高, 很难应用到应用市场级别数十万的应用检测.

  3. Zhou 等人 [7] 提出了基于程序依赖图的模块解耦技术来把应用程序的代码划分为核心模块和次 要模块. 首先根据 Dalvik 字节码建立程序依赖图, 使用聚类算法来将程序依赖图中的包聚类. 然后根 据应用程序配置文件的一些基本信息 (活动、服务、内容提供者、接收者等) 来确定已经聚类的模块中 哪些是主要模块和次要模块. 应用程序之间的比较是通过从主模块中提取出来的一些语义的信息, 如 应用程序申请的权限和 Android API 的调用等. 作者同时提出了一个线性搜索算法来降低在一堆应 用中检测重打包的复杂度, 即不需要两两之间都要比较, 只需比较 O(n logn) 个应用对即可. 4.

可用做法(猜测)

  1. 基于重打包的判断条件,为了高效率提取核心代码,可能需要过滤正常的第三方库,如广告库,社交库,开发库等,过滤条件(文件结构目录,文件MD5等),Sdk文件目录可以尽量使用第三方路径。

  2. Keytool 可以用来提取应用程序的签名信息,签名MD5,SHA具有唯一性,所以每次签名必重新生成签名。

  3. Android5.0 以后安全性要求较高的应用应该使用 window.setFlag (LayoutParam.FLAG_SECURE) 禁止录屏。

  4. 假定